<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue的生命周期</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>

<body>

    <!-- 
    -->
    <div id="app">
        <h1>{{msg}}</h1>

        <h3>计算器：{{counter}}</h3>
        <h3 v-text="counter"></h3>

        <button @click="add">点我加1</button>
        <button @click="destroy">点我销毁</button>
    </div>

    <script>

        const vm = new Vue({
            el: '#app',
            data: {
                msg: 'Vue的生命周期',
                counter: 0
            },
            methods: {
                add() {
                    this.counter++
                },
                destroy() {
                    this.$destroy()
                },
                m() {
                    console.log('m....')
                }
            },
            watch: {
                counter() {
                    console.log('counter被监视一次！');
                }
            },
            /*
            1.初始阶段：虚拟dom生成
                el有，template也有，最终编译template模板语句
                el有，template没有，最终编译el模板语句
                el没有的时候，需要手动调用 vm.$mount(el) 进行手动挂载，然后流程才能继续（判断template是否存在，同上两条判断）

            结论：
                流程要想继续，el必须存在
                el和template同时存在，优先选择template，如果没有template，才会选择el
            */
            beforeCreate() {
                //创建前
                //创建前指的是：数据代理和数据监测的创建前
                //此处还无法访问data中的数据，包括methods也是无法访问的
                console.log('beforeCreate', this.counter)  //此处 this.counter 为 undefined
                this.m() //调用methods报错了，不存在
            },
            created() {
                //创建后
                //创建后表示数据代理和数据监测创建完毕，可以访问data中的数据了
                console.log('created', this.counter)  //此处可以
                this.m()  //此处可以
            },
            /*
            2.挂载阶段：真实dom生成
            */
            beforeMount() {
                //挂载前
                console.log('beforeMount')

                //debugger
                //此时在浏览器控制台输入此语句，可以修改h1的内容，但断点继续，后面周期会将虚拟dom挂载为真实dom，覆盖test内容
                //document.querySelector('h1').innerText='test'  
            },
            mounted() {
                //挂载后
                console.log('mounted')
                console.log(this.$el)
                console.log(this.$el instanceof HTMLElement) //判断el是否为一个真实的dom

                //debugger
                //此时在浏览器控制台输入此语句，这时已经将虚拟dom挂载为真实dom完成，这里继续操作dom中内容，可以最终生效
                //document.querySelector('h1').innerText='hehe'  

            },
            //3.更新阶段：虚拟dom重新渲染和修补
            beforeUpdate() {
                //更新前
                console.log('beforeUpdate');

                // debugger
                // 点击add事件后，进入断点，此时虚拟dom已经+1，但页面没有发生改变（即真实dom无改动）
            },
            updated() {
                //更新后
                console.log('updated');

                // debugger
                // 点击add事件后，进入断点，此时虚拟dom已经+1，页面也+1
            },
            //4.销毁阶段：卸载监视器、子组件、自定义事件监听器（不是卸载vm，vm还是存在的）
            beforeDestroy() {
                //销毁前
                console.log('beforeDestroy');
                console.log(this); //vm依然存在

                // debugger
                this.counter = 100 //此处无法更改页面数据，但内存中已经修改了
            },
            destroyed() {
                //销毁后
                console.log('destroyed');
                console.log(this); //vm依然存在 

                // debugger

                //这个不常用，react里面没有这个钩子，一般使用上一个即可
            }
        })

    </script>

</body>

</html>